﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace AgFractal.Controls
{
    public partial class ImagePresenter : UserControl
    {
        public ImagePresenter()
        {
            InitializeComponent();
            SizeChanged += (s, e) => SetSize(ActualWidth, ActualHeight);
        }

        private bool _IsDraggable;
        public bool IsDraggable
        {
            get { return _IsDraggable; }
            set
            {
                _IsDraggable = value;
                if (value)
                    Cursor = Cursors.Hand;
                else
                {
                    drag = false;
                    Cursor = null;
                }
            }
        }

        internal void SetSize(double width, double height)
        {
            this.width = width;
            this.height = height;
            cnv.Width = width;
            cnv.Height = height;
            cnv.Clip = new RectangleGeometry
            {
                Rect = new Rect(0, 0, width, height)
            };
            img.Height = height;
            img.Width = width;
        }

        public event EventHandler<DraggedEventArgs> Dragged;

        private double width;
        private double height;

        internal void SetImage(ImageSource source)
        {
            Storyboard1.Stop();

            imgScale.ScaleX = 1;
            imgScale.ScaleY = 1;
            img.RenderTransformOrigin = new Point(0.5, 0.5);
            ResetImagePos();
            img.Source = source;
        }

        internal void Zoom(Point pos, double factor)
        {
            img.RenderTransformOrigin = new Point(pos.X / img.ActualWidth, pos.Y / img.ActualHeight);
            var zoomx = ((System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames)Storyboard1.Children[0]).KeyFrames[0];
            zoomx.Value = factor;
            var zoomy = ((System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames)Storyboard1.Children[1]).KeyFrames[0];
            zoomy.Value = factor;

            //zoomX.Value = factor;
            //zoomY.Value = factor;
            Storyboard1.Begin();
        }

        bool drag;
        Point startPoint;
        private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!IsDraggable)
                return;
            drag = true;
            img.CaptureMouse();
            startPoint = e.GetPosition(cnv);
        }

        private void Image_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                var currentPoint = e.GetPosition(cnv);

                double newTop;
                if (KeyboardState.ShiftDown)
                    newTop = 0;
                else
                    newTop = currentPoint.Y - startPoint.Y;
                double maxV = height * 0.75;
                if (newTop > maxV) newTop = maxV;
                if (-newTop > maxV) newTop = -maxV;
                img.SetValue(Canvas.TopProperty, newTop);

                double newLeft;
                if (KeyboardState.CtrlDown)
                    newLeft = 0;
                else
                    newLeft = currentPoint.X - startPoint.X;
                double maxH = width * 0.75;
                if (newLeft > maxH) newLeft = maxH;
                if (-newLeft > maxH) newLeft = -maxH;
                img.SetValue(Canvas.LeftProperty, newLeft);
            }
        }

        private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!drag) return;

            drag = false;
            img.ReleaseMouseCapture();
            if (Dragged != null)
            {
                var currentPoint = e.GetPosition(cnv);
                Dragged(this, new DraggedEventArgs(
                        currentPoint.Y - startPoint.Y,
                        currentPoint.X - startPoint.X));
            }
        }

        private void ResetImagePos()
        {
            img.SetValue(Canvas.LeftProperty, 0d);
            img.SetValue(Canvas.TopProperty, 0d);
        }
    }
}